package com.example.onlineeducation.repository

import com.example.onlineeducation.data.entity.*
import com.example.onlineeducation.mapper.OfflineStudyLiveListMapper
import com.example.onlineeducation.mapper.UserProJoinInfoMapper
import com.example.onlineeducation.data.json.UploadFileResultJson
import com.example.onlineeducation.mapper.*
import com.example.onlineeducation.net.ApiService
import com.google.gson.JsonObject
import com.yc.jetpacklib.base.YcRepository
import com.yc.jetpacklib.extension.ycFlow
import com.yc.jetpacklib.extension.ycIsEmpty
import com.yc.jetpacklib.extension.ycIsNotEmpty
import com.yc.jetpacklib.extension.ycToRequestBody
import com.yc.jetpacklib.net.YcResult
import com.yc.jetpacklib.recycleView.YcPager
import kotlinx.coroutines.flow.*
import okhttp3.MultipartBody
import org.json.JSONException
import pageListToDataSource
import ycGetDataNoNull

/**
 * Creator: yc
 * Date: 2022/4/20 16:08
 * UseDes:线下相关仓库
 */
class OfflineRepository(private val apiService: ApiService) : YcRepository() {
    private val mOfflineStudyLiveListMapper by lazy { OfflineStudyLiveListMapper() }
    private val mOfflineStudyReplaceSignListMapper by lazy { OfflineStudyReplaceSignListMapper() }

    /**
     * 获取线下学习活动列表
     */
    fun getStudyLiveList(proId: String): Flow<YcResult<List<OfflineStudyLiveListEntity>?>> = ycFlow {
        val json = apiService.getOfflineStudyLiveList(proId)
        send(YcResult.Success(mOfflineStudyLiveListMapper.map(json.dataList)))
    }

    private val mOfflineStudyLiveDetailMapper by lazy { OfflineStudyLiveDetailMapper() }

    /**
     * 获取线下学习活动详情
     */
    fun getOfflineStudyLiveDetail(proId: String, studyLiveId: String): Flow<YcResult<OfflineStudyLiveDetailEntity>> = ycFlow {
        val json = apiService.getOfflineStudyLiveDetail(proId, studyLiveId)
        send(YcResult.Success(mOfflineStudyLiveDetailMapper.map(json.data)))
    }

    /**
     * 获取线下学习列表
     */
    fun getOfflineJoinActiveList(proId: String): Flow<YcResult<List<OfflineStudyLiveListEntity>?>> = ycFlow {
        val json = apiService.getOfflineJoinActiveList(proId)
        send(YcResult.Success(mOfflineStudyLiveListMapper.map(json.dataList)))
    }


    /**
     * 线下学习活动-签到/签退
     * @param studyLiveId String    线下学习活动id
     * @param address String        签到点的地址
     * @param lat String            签到点的纬度
     * @param lng String            签到点的经度
     * @param userName String       签到用户名称
     * @param userPhone String      签到用户手机号
     * @param signType String       签到类型 1-签到 2-签退
     */
    fun offlineStudyLiveSignInOrSignOut(
        studyLiveId: String,
        address: String,
        lat: String,
        lng: String,
        userName: String,
        userPhone: String,
        signType: String
    ): Flow<YcResult<String>> = ycFlow {
        val requestjson = JsonObject()
        requestjson.addProperty("activeInfoId", studyLiveId)
        requestjson.addProperty("address", address)
        requestjson.addProperty("lat", lat)
        requestjson.addProperty("lng", lng)
        requestjson.addProperty("name", userName)
        requestjson.addProperty("userPhone", userPhone)
        requestjson.addProperty("signType", signType)
        val json = apiService.offlineStudyLiveSignInOrSignOut(requestjson.toString().ycToRequestBody())
        send(YcResult.Success(json.data!!))
    }

    /**
     * 提交考试详情
     */
    fun submitOfflineExamDetail(id: String, costTime: String, mediaUrl: String? = null, point: String, testDate: String): Flow<YcResult<Any?>> =
        ycFlow {
            val requestData = JsonObject()
            try {
                requestData.addProperty("id", id)
                requestData.addProperty("costTime", costTime)//考试时长
                if (mediaUrl.ycIsNotEmpty()) requestData.addProperty("mediaUrl", mediaUrl)//卷面图
                requestData.addProperty("point", point)//分数
                requestData.addProperty("testDate", testDate)//考试日期
            } catch (e: JSONException) {
                e.printStackTrace()
            }
            val requestBody = requestData.toString().ycToRequestBody()
            val json = apiService.submitOfflineExamDetail(requestBody)
            send(YcResult.Success(json))
        }


    /*
    * 提交考试详情（多图片）
    * */
    private val mUploadMultipleFileMapper by lazy { UploadMultipleFileMapper() }
    fun uploadMultipleFile(partLis: List<MultipartBody.Part>): Flow<YcResult<List<String>?>> = ycFlow {
        val json = apiService.uploadMultipleFile(partLis).ycGetDataNoNull()
        send(YcResult.Success(mUploadMultipleFileMapper.map(json.mediaInfolist)))
    }


    /*
    * 单文件上传
    * */
    fun uploadFile(partLis: List<MultipartBody.Part>): Flow<YcResult<UploadFileResultJson?>> = ycFlow {
        val json = apiService.uploadFile(partLis)
        send(YcResult.Success(json.data))
    }



    /**
     * 获取用户在x项目的参加活动信息
     */
    private val mUserProJoinInfoMapper by lazy { UserProJoinInfoMapper() }
    fun getJoinInfo(proId: String): Flow<YcResult<UserProJoinInfoEntity>> = ycFlow {
        val json = apiService.getJoinInfo(proId)
        send(YcResult.Success(mUserProJoinInfoMapper.map(json.data)))
    }


    /**
     * 线下考试列表
     */
    private val mOfflineExamListMapper by lazy {
        OfflineExamListMapper()
    }

    fun getOfflineExamList(proId: String) = YcPager.getPagerFlow { pageIndex, pageSize ->
        apiService.getOfflineExamList(proId, pageIndex, pageSize).pageListToDataSource(mOfflineExamListMapper)
    }

    /**
     * 线下考试_人员考试记录列表
     */
    private val mOfflineExamRecordListMapper by lazy {
        OfflineExamRecordListMapper()
    }

    fun getOfflineExamRecordList(proId: String? = null, examId: String? = null, personName: String? = null) = YcPager.getPagerFlow { pageIndex, pageSize ->
        apiService.getOfflineExamRecordList(proId = proId, examId = examId, personName = personName, pageIndex = pageIndex, pageSize = pageSize)
            .pageListToDataSource(mOfflineExamRecordListMapper)
    }


    private val mOfflineExamDetailMapper by lazy {
        OfflineExamDetailMapper()
    }

    fun getOfflineExamRecordDetail(proId: String, examId: String, id: String): Flow<YcResult<OfflineExamDetailEntity?>> = ycFlow {
        val json = apiService.getOfflineExamRecordList(proId = proId, examId = examId, id = id, pageIndex = 1, pageSize = 1)
        if(json.result==null||json.result.dataList.ycIsEmpty()){
            send(YcResult.Success(mOfflineExamDetailMapper.map(null)))
        }else{
            send(YcResult.Success(mOfflineExamDetailMapper.map(json.result.dataList?.get(0))))
        }

    }

    /**
     * 发送验证码
     */
    fun sendSignSmsCode(phoneNum: String): Flow<YcResult<String>> = ycFlow {
        val jsonData = apiService.sendSignSmsCode(phoneNum).ycGetDataNoNull()
        send(YcResult.Success(jsonData))
    }

    /**
     * 获取代签到列表
     */
    fun getReplaceSignList(activeInfoId: String): Flow<YcResult<List<OfflineStudyReplaceSignListEntity>?>> =
        ycFlow {
            val json = apiService.getReplaceSignList(activeInfoId)
            send(YcResult.Success(mOfflineStudyReplaceSignListMapper.map(json.dataList)))
        }

    fun replaceSign(
        activeInfoId: String,
        address: String,
        lat: String,
        lng: String,
        reSignInMediaId: String,
        signInEntity: SignInEntity
    ): Flow<YcResult<String?>> =
        ycFlow {
            val requestData = JsonObject()
            try {
                requestData.addProperty("activeInfoId", activeInfoId)
                requestData.addProperty("address", address)//考试时长
                requestData.addProperty("lat", lat)//卷面图
                requestData.addProperty("lng", lng)//分数
                requestData.addProperty("name", signInEntity.name)//考试日期
                requestData.addProperty("phone", signInEntity.phone)//卷面图
                requestData.addProperty("idCard", signInEntity.idCard)//分数
                requestData.addProperty("smsCode", signInEntity.smsCode)//考试日期
                requestData.addProperty("reSignInMediaId", reSignInMediaId)//考试日期
                requestData.addProperty("replaceRemark", signInEntity.replaceRemark)//卷面图
                requestData.addProperty("signType", "1")//分数
            } catch (e: JSONException) {
                e.printStackTrace()
            }
            val requestBody = requestData.toString().ycToRequestBody()
            val json = apiService.replaceSign(requestBody)
            send(YcResult.Success(json.data))
        }

    fun replaceSignOut(
        activeInfoId: String,
        address: String,
        lat: String,
        lng: String,
        reSignOutMediaId: String,
        replacePersonId: String
    ): Flow<YcResult<String?>> =
        ycFlow {
            val requestData = JsonObject()
            try {
                requestData.addProperty("activeInfoId", activeInfoId)
                requestData.addProperty("address", address)//考试时长
                requestData.addProperty("lat", lat)//卷面图
                requestData.addProperty("lng", lng)//分数
                requestData.addProperty("reSignOutMediaId", reSignOutMediaId)//考试日期
                requestData.addProperty("replacePersonId", replacePersonId)//卷面图
                requestData.addProperty("signType", "2")//分数
            } catch (e: JSONException) {
                e.printStackTrace()
            }
            val requestBody = requestData.toString().ycToRequestBody()
            val json = apiService.replaceSign(requestBody)
            send(YcResult.Success(json.data))
        }
}